'use strict';

/**
 * 获取指定日期的差值并格式化输出
 * @param {*} start 
 * @param {*} end 
 * @param {*} format:
 *            YYYY| 累计年数
 *            MM| 累计月数
 *            DD| 累计天数
 *            Mm| 周年后过多少个月
 *            dd| 周年月后过多少天
 *            hh| 周年月日后过多少小时
 *            mm| 周年月日时后过多少小时
 *            ss| 周年月日时分后过多少秒
 * @returns 
 */
function getDiff(start, end) {
  let startDate = {
    y: start.getFullYear(),
    m: start.getMonth() + 1,
    d: start.getDate(),
    t: start.getTime()
  };
  let endDate = {
    y: end.getFullYear(),
    m: end.getMonth() + 1,
    d: end.getDate(),
    t: end.getTime()
  };
  return function (format) {
    let res = '';

    switch (format) {
      case 'YYYY':
        res = endDate.y - startDate.y;
        if (endDate.m < startDate.m) {
          res--;
        }
        break;

      case 'MM':
        if (endDate.m < startDate.m) {
          res = endDate.m - startDate.m + (endDate.y - startDate.y) * 12;
        } else {
          res = endDate.m - startDate.m + (endDate.y - startDate.y + 1) * 12;
        }

        if (endDate.d < startDate.d) {
          res--;
        }
        break;

      case 'DD':
        res = Math.floor((endDate.t - startDate.t) / (1000 * 60 * 60 * 24)) + 2;
        break;

      case 'Mm':
        if (endDate.m < startDate.m) {
          res = endDate.m - startDate.m + 12;
        } else {
          res = endDate.m - startDate.m;
        }

        if (endDate.d < startDate.d) {
          res--;
        }
        break;

      case 'dd':
        res = endDate.d - startDate.d;
        break;

      case 'hh':
        res = Math.floor((endDate.t - startDate.t) / (1000 * 60 * 60)) % 24;
        break;

      case 'mm':
        res = Math.floor((endDate.t - startDate.t) / (1000 * 60)) % 60;
        break;

      case 'ss':
        res = Math.floor((endDate.t - startDate.t) / 1000) % 60;
        break;

      default:
        break;
    }

    // return res < 10 ? '0'+res : res;
    return res;
  }
}

/**
 * Class
 * @param {*} options 
 * @returns 
 */
function Memory(options) {
  let root = this;
  root.init(options);
  return root;
}

Memory.prototype.init = function (options) {
  let root = this;
  root['config'] = options;
  if (typeof document === 'undefined') {
    console && console.warn('Failed to install Memory');
    return;
  }
  // start
  !!options && root._init();
  return root;
}

Memory.prototype._init = function () {
  let root = this;
  root.timerTask = null;
  root.el = null;

  let {
    el,
    start,
    template,
    delay,
  } = root.config;

  if (!el) {
    throw new Error('must bind a dom element!')
  }

  if (!start) {
    throw new Error('must set start time');
  }

  const id = el.replace('#', '');
  root.el = document.getElementById(id);

  delay = Number(delay);

  if (!delay || isNaN(delay)) {
    delay = 500;
  }

  if (!template) {
    template = '第YYYY年MM月DD天，hh时mm分ss秒';
  }

  root.config.delay = delay;
  root.config.template = template;

  document.addEventListener('DOMContentLoaded', function(){
    root.render();
  });

  document.addEventListener('beforeunload', function(){
    root.destroy();
  });
}

Memory.prototype.render = function (context) {
  let root = context || this;
  let {
    start: _start,
    template,
    delay,
    tag = 'i',
  } = root.config;

  let dom = root.el;
  let start = new Date(_start);

  const execute = () => {
    // console.log('render', this);
    let end = new Date();
    let diff = getDiff(start, end);
    let content = template.replace(/(YYYY|MM|DD|Mm|dd|hh|mm|ss)/g, function () {
      return '<'+tag+'>'+ diff(arguments[0]) +'</'+tag+'>'
    });
    dom.innerHTML = content;
  }
  
  if (!dom) {
    console && console.warn('Could not found dom to mount');
  } else if (/(hh|mm|ss)/.test(template)){
    root.timerTask = setInterval(execute, delay);
  } else {
    execute();
  }

}

Memory.prototype.destroy = function () {
  let root = this;
  if (root && root.timerTask) {
    clearInterval(root.timerTask);
  }
}
